package com.urea.framework.web.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.urea.common.core.domain.AjaxResult;
import com.urea.common.core.domain.entity.Customer;
import com.urea.common.core.domain.model.LoginUser;
import com.urea.common.exception.ServiceException;
import com.urea.common.utils.SecurityUtils;
import com.urea.common.utils.sign.EncryptUtils;
import com.urea.system.constants.BusinessConstants;
import com.urea.system.domain.*;
import com.urea.system.domain.vo.CustomerAccountVo;
import com.urea.system.domain.vo.CustomerVo;
import com.urea.system.domain.vo.OrderVo;
import com.urea.system.domain.vo.PayVo;
import com.urea.system.service.*;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.OrderUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 类描述:
 *
 * @author fangXu
 * @version 1.0
 * @date 2023/8/10 14:49
 */
@Service
@Slf4j
public class WxMaUserServiceImpl  {
    @Autowired
    private  WxMaService wxMaService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private IRechargePackageService packageService;
    @Autowired
    private ICustomerAccountService customerAccountService;
    @Autowired
    private ICustomerAccountDetailService accountDetailService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IPayInfoService payInfoService;
    @Autowired
    private IAgentTerminalService agentTerminalService;
    @Autowired
    private IFleetTerminalService fleetTerminalService;
    @Autowired
    private IPayService payService;


    /**
     * 小程序登录
     *
     * @param vo 用户信息
     * @return 结果
     */
    public AjaxResult login(CustomerVo vo) {
        if (StringUtils.isBlank(vo.getCode())) {
            return AjaxResult.error("code不可为空");
        }
        if (!wxMaService.switchover(vo.getAppId())) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", vo.getAppId()));
        }

        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(vo.getCode());
            log.info("##########小程序登录结果:{}################",session.toString());
            // 获取用户openId
            //WxMaJscode2SessionResult(sessionKey=6xx2EaXVI1JnrvfLx8QqsA==, openid=o6a4K5NRLxAGD29QCjz7eS39hG_I, unionid=null)
            String openid = session.getOpenid();
//            String openid = "o6a4K5NRLxAGD29QCjz7eS39hG_I";
            if (StringUtils.isBlank(openid)){
                return AjaxResult.error("openid为空,请稍候重试");
            }
            LoginUser loginUser = new LoginUser();
            ReentrantLock lock = new ReentrantLock();
            // 获取用户手机号信息
            WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(vo.getPhoneCode());
            log.info("########获取手机号结果:{}#########",phoneNoInfo.toString());
            // 根据手机号获取用户信息
            Customer customer = customerService.getOne(Wrappers.lambdaQuery(Customer.class).eq(Customer::getPhone,phoneNoInfo.getPhoneNumber()));
            loginUser.setCustomerUser(customer);
            String phone ;
            if (Objects.isNull(customer)){
                lock.lock();
                try {
                    // 用户为空,创建用户信息
                    Customer user = new Customer();
                    BeanUtils.copyProperties(vo,user);
                    user.setPhone(phoneNoInfo.getPhoneNumber());
                    user.setOpenId(openid);
                    user.setAccount(user.getPhone());
                    user.setPassword("123456");
                    customerService.save(user);
                    loginUser.setCustomerUser(user);
                    loginUser.setUserId(user.getId());
                    phone = phoneNoInfo.getPhoneNumber();
                    // 创建账户信息
                    CustomerAccount account = new CustomerAccount();
                    account.setBalance(BigDecimal.ZERO);
                    account.setCreatedTime(LocalDateTime.now());
                    account.setCustomerId(user.getId());
                    customerAccountService.save(account);
                } finally {
                    lock.unlock();
                }
            }else{
                if (StringUtils.isBlank(customer.getOpenId())){
                    customerService.update(Wrappers.lambdaUpdate(Customer.class).eq(Customer::getId,customer.getId())
                            .set(Customer::getOpenId,openid));
                }
                loginUser.setUserId(customer.getId());
                phone = customer.getPhone();
            }
            // 获取token 返回前端
            String token = tokenService.createToken(loginUser);
            Map<String,String> map = new HashMap<>();
            map.put("token",token);
            map.put("phone",phone);
            return AjaxResult.success(map);
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.toString());
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }

}
